RouterOS 通过 BGP 实现动态路由部署

在不久前我遇到了这样一个需求:A、B 两地的 ROS 路由器通过 WireGuard 连接,B 地需要通过 A 来访问某些仅连接到 A 路由器的网段,这些网段可能会变化,手动为 B 添加路由信息太过麻烦,于是我想到了用 BGP 解决这个问题。

前言

由于实际配置完成已经过去了一段时间,我是凭着回忆写下的这段文字,因此部分细节可能存在问题。如果文中有错误的地方,还请多多包涵,也可以通过电子邮件(见侧栏)来告知我,方便我及时修正,感谢!

IPIP 隧道

由于 WireGuard 会通过 AllowedIPs 做入站路由过滤,因此通过 WG 隧道宣告 BGP 路由之后,还需要手动调整 AllowedIPs。由于某些原因,我只能通过 WG 隧道连接两地。因此,我在 WG 隧道之上,又运行了一条 IP 隧道,通过 IP 隧道进行路由宣告和路由转发,避开了 WG 隧道 AllowedIPs 的限制。

/interface/ipip
add name=ipip-to-b local-address=<WG本地地址> remote-address=<WG对端地址>
/ip/address
add address=192.168.55.1/30 interface=ipip-to-b

目前两机的路由信息如下:

路由器 网关地址 隧道地址
A 192.168.66.1 192.168.55.1
B 192.168.77.1 192.168.55.2

新增动态路由条目

我们需要在 A 路由器上维护一个网段表,包含要发布到 B 的路由条目,供之后 BGP 配置中使用。

/ip/firewall/address-list
add list=bgp-networks address=10.9.0.0/24
add list=bgp-networks address=10.10.0.0/24

新增 BGP 过滤规则

如果不添加 BGP 过滤规则,BGP 会将 A 的所有路由信息发布到 B,容易造成奇怪的网络问题,因此我们需要在 A 上编写过滤规则,让 BGP 只发布我们要发布的网段。

/routing/filter/rule
add chain=BGP-OUTPUT rule="if (dst in bgp-networks) { accept; }"
add chain=BGP-OUTPUT rule="reject;"

当 BGP 进行路由宣告时,会由上面的脚本进行过滤,大意为:如果要发布的网段在指定网段表内,允许宣告;否则则拒绝宣告。脚本中的 bgp-networks 引用的是网段表中的 bgp-networks

新建 BGP 连接

首先在 A 机新建一个 BGP 实例,router-id 填写局域网网关地址即可,AS号可以自己写。

/routing/bgp/instance
add name=bgp-instance router-id=192.168.66.1 as=65001

B 机也是一样,AS 号注意和 A 机要不同。

/routing/bgp/instance
add name=bgp-instance router-id=192.168.77.1 as=65002

然后先在 A 机新建 BGP 连接:

/routing/bgp/connection
add name=to-b-bgp instance=bgp-instance remote.address=192.168.55.2/32 remote.as=65002 local.role=ebgp routing-table=main output.network=bgp-networks output.filter-chain=BGP-OUTPUT

remote.address 是对端 B 机的隧道地址,remote.as 是 B 机的 AS 号。

然后在 B 机新建 BGP 连接:

/routing/bgp/connection
add name=to-a-bgp instance=bgp-instance remote.address=192.168.55.1/32 remote.as=65001 local.role=ebgp routing-table=main

B 机的这段命令中,remote.address 是对端 A 机的隧道地址,remote.as 是 A 机的 AS 号。

完成上述操作后,在BGP Session中就能看到建立的 BGP 连接,在 B 机路由表中也能看到 A 机宣告的路由地址。

/routing/bgp/session/print
/ip/route/print

Powered By Hexo & Theme Veni